use anyhow::Result;
use tokio::net::{TcpListener, TcpStream};
use tracing::{error, info};

#[tokio::main]
async fn main() -> Result<()> {
    tracing_subscriber::fmt::init();
    let addr = "127.0.0.1:6379";
    let listener = TcpListener::bind(addr).await?;
    info!("Listening on: {}", addr);

    loop {
        let (socket, addr) = listener.accept().await?;
        info!("Accepted connection from: {}", addr);

        tokio::spawn(async move {
            if let Err(err) = handle_connection(socket).await {
                error!("Error handling connection: {}", err);
            }
        });
    }
}

async fn handle_connection(socket: TcpStream) -> Result<()> {
    loop {
        socket.readable().await?;
        let mut buffer = Vec::with_capacity(4096);
        match socket.try_read_buf(&mut buffer) {
            Ok(0) => break,
            Ok(n) => {
                info!("Received {} bytes", n);
                let command = String::from_utf8_lossy(&buffer);
                info!("Received command: {}", command);
            }
            Err(err) if err.kind() == std::io::ErrorKind::WouldBlock => {
                continue;
            }
            Err(err) => {
                error!("Error reading from socket: {}", err);
                break;
            }
        }
    }

    Ok(())
}
